package com.smedi.ismedi.notification.core.application.service.impl;

import cn.hutool.core.util.IdUtil;
import com.smedi.ismedi.notification.core.application.command.SendSmsCommand;
import com.smedi.ismedi.notification.core.application.service.SmsNotificationApplicationService;
import com.smedi.ismedi.notification.core.domain.aggregatemodel.SmsLog;
import com.smedi.ismedi.notification.core.domain.aggregatemodel.SmsTemplate;
import com.smedi.ismedi.notification.core.domain.service.SmsLogDomainService;
import com.smedi.ismedi.notification.core.domain.service.SmsTemplateDomainService;
import com.smedi.ismedi.notification.core.infrastructure.constant.ConstantField;
import com.smedi.ismedi.notification.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.notification.core.port.service.SmsClientRemoteApiService;
import com.smedi.ismedi.web.starter.exception.LogicException;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: xulinjun
 * @Date: 2021-7-2 10:41
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SmsNotificationApplicationServiceImpl implements SmsNotificationApplicationService {
    private final SmsTemplateDomainService smsTemplateDomainService;

    private final SmsClientRemoteApiService smsClientRemoteApiService;

    private final SmsLogDomainService smsLogDomainService;

    @Override
//    @Async(AsyncThreadPoolConfig.asyncThreadName)
    @Transactional(rollbackFor = Exception.class)
    public void sendShortMessage(SendSmsCommand sendSmsCommand) {
        SmsTemplate smsTemplate = null;
        // 获取短信模板
        if (null != sendSmsCommand.getSmsTemplateId()) {
            smsTemplate = smsTemplateDomainService.queryTemplateBySmsTemplateId(sendSmsCommand.getSmsTemplateId());
        }
        if (null != sendSmsCommand.getSmsTemplateName()) {
            smsTemplate = smsTemplateDomainService.queryTemplateBySmsTemplateName(sendSmsCommand.getSmsTemplateName());
        }

        // 校验接收人员
        List<String> mobiles = sendSmsCommand.getReceivers();
        if (mobiles.size() <= 0) {
            throw LogicException.raise(CustomError.RECEIVERS_EMPTY);
        }
        // 校验参数与模板是否匹配
        if (smsTemplate.getParameters() != sendSmsCommand.getParameters().size()) {
            throw LogicException.raise(CustomError.PARAMETERS_NOT_FIX_TEMPLATE);
        }

        List<String> mobilesChanged = new ArrayList<>();
        for (String mobile : mobiles) {
            if(!StringUtils.startsWith(mobile, "+86")){
                mobilesChanged.add("+86"+mobile);
            }
        }

        // 生成batchId
        String batchId = IdUtil.objectId();
        // 获取实际发送的短信信息
        String actualMessageContent = smsTemplate.getTemplateContent();
        for (int i = 1; i <= smsTemplate.getParameters(); i++) {
            actualMessageContent = actualMessageContent.replaceAll("\\{" + i + "\\}", sendSmsCommand.getParameters().get(i - 1));
        }

        // 发送短信信息
        List<SmsLog> smsLogs = new ArrayList<>();

        try {

            SendSmsResponse sendSmsResponse = smsClientRemoteApiService.send(mobilesChanged, sendSmsCommand.getParameters(), smsTemplate.getTencentTemplateId(), ConstantField.defaultSign, batchId);

            for (SendStatus status : sendSmsResponse.getSendStatusSet()) {
                if (status.getSessionContext().equals(batchId)) {
                    smsLogs.add(new SmsLog()
                            .setBatchId(batchId)
                            .setMessageContent(actualMessageContent)
                            .setErrorMessage(status.getMessage())
                            .setStatusCode(status.getCode())
                            .setMobile(status.getPhoneNumber())
                            .setTemplateId(sendSmsCommand.getSmsTemplateId())
                            .setSucceed(true)
                            .setSerialNo(status.getSerialNo()));
                }
            }
        } catch (Exception e) {
            for (String mobile : mobilesChanged) {
                smsLogs.add(new SmsLog()
                        .setBatchId(batchId)
                        .setMessageContent(actualMessageContent)
                        .setMobile(mobile)
                        .setTemplateId(sendSmsCommand.getSmsTemplateId())
                        .setSucceed(false)
                        .setErrorMessage(e.getMessage()));
            }
        }

        smsLogDomainService.batchSaveSmsLogs(smsLogs);
    }
}
